import 'dart:convert';
import 'dart:ffi';
import 'dart:io';

import 'package:device_info_plus/device_info_plus.dart';
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_device_id/flutter_device_id.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:package_info/package_info.dart';
import 'package:photo_frame/user/user_manager.dart';
import 'package:photo_frame/utils/a_logger.dart';

class HttpManager {
  late Dio _dio;
  late Map<String, dynamic> commonBodyParams;
  static final HttpManager instance = HttpManager._();

  Dio get dio => _dio;

  HttpManager._();

  Future<void> init() async {
    await loadCommonBodyParams();
    final options = BaseOptions(
      // baseUrl: 'https://www.maodou9527.cn',
      baseUrl: 'https://www.ifotocube.com',
      validateStatus: (status) => true,
      connectTimeout: const Duration(seconds: 15),
      receiveTimeout: const Duration(seconds: 15),
      responseType: ResponseType.json,
    );

    _dio = Dio(options);
    (_dio.httpClientAdapter as IOHttpClientAdapter).createHttpClient = () {
      return HttpClient()
        ..badCertificateCallback = (cert, host, port) {
          return true;
        };
    };

    _dio.interceptors
        .add(LogInterceptor(requestBody: true, responseBody: true));
  }

  Future<BaseResponse> doRequest(
    String path, {
    HttpMethod method = HttpMethod.POST,
    bool showTost = true,
    Map<String, dynamic>? parameters,
  }) async {
    Options options = Options(method: method.value, headers: {
      "Authorization": UserManager.instance.getToken() ?? "",
    });

    Object? data;
    Map<String, dynamic>? queryParameters;
    switch (method) {
      case HttpMethod.GET:
        queryParameters = parameters;
      case HttpMethod.POST:
        parameters ??= {};
        parameters.addAll(commonBodyParams);
        parameters.removeWhere((k, v) => v == null);
        data = parameters;
    }

    BaseResponse baseResponse = BaseResponse();
    try {
      final dioResponse = await _dio.request(
        path,
        data: data != null ? jsonEncode(data) : null,
        queryParameters: queryParameters,
        options: options,
      );
      baseResponse.code = dioResponse.data?["code"];
      baseResponse.data = dioResponse.data?['data'];
      baseResponse.msg = dioResponse.data?["msg"];
      if (!baseResponse.isSuccess && baseResponse.msg?.isNotEmpty == true && showTost) {
        Fluttertoast.showToast(msg: baseResponse.msg!);
      }
    } on DioException catch (e) {
      baseResponse.code = -1;
      baseResponse.msg = "网络异常";
    }
    return baseResponse;
  }

  Dio getDio() {
    return _dio;
  }

  Future<void> loadCommonBodyParams() async {
    final deviceInfoPlugin = DeviceInfoPlugin();
    if (defaultTargetPlatform == TargetPlatform.android) {
      commonBodyParams =
          await _readAndroidBuildData(await deviceInfoPlugin.androidInfo);
    } else if (defaultTargetPlatform == TargetPlatform.iOS) {
      commonBodyParams =
          await _readIosDeviceInfo(await deviceInfoPlugin.iosInfo);
    }
    final flutterDeviceIdPlugin = FlutterDeviceId();
    commonBodyParams['did'] = (await flutterDeviceIdPlugin.getDeviceId()) ?? '';
    return;
  }

  _readAndroidBuildData(AndroidDeviceInfo build) async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    return <String, dynamic>{
      'model': build.model,
      'brand': build.brand,
      'language': WidgetsBinding.instance.window.locale.languageCode,
      'sys_ver': build.version.sdkInt,
      'version': packageInfo.buildNumber,
      'channel': 'googleplay',
      'type': '2',
    };
  }

  _readIosDeviceInfo(IosDeviceInfo data) async {
    PackageInfo packageInfo = await PackageInfo.fromPlatform();
    return <String, dynamic>{
      'model': data.model,
      'brand': 'Apple',
      'language': WidgetsBinding.instance.window.locale.languageCode,
      'sys_ver': data.systemVersion,
      'version': packageInfo.buildNumber,
      'channel': 'appstore',
      'type': '3'
    };
  }
}

enum HttpMethod {
  GET("GET"),
  POST("POST");

  const HttpMethod(this.value);

  final String value;
}

class BaseResponse {
  int? code;
  String? msg;

  dynamic data;

  bool get isSuccess {
    return (code == 0);
  }
}

uploadFinish(List<String>? frameIds) async {
  ALogger.e("uploadFinish ${frameIds}");
  if (frameIds?.isNotEmpty != true) {
    return;
  }
  var filterId = frameIds!.where((e) => e.isNotEmpty == true).toSet();
  ALogger.e("uploadFinish-filterId ${filterId}");
  if (filterId.isNotEmpty != true) {
    return;
  }
  return HttpManager.instance.doRequest("/api/uploadfinish",
      parameters: {"frame_ids": filterId.toList()}).then((e) {
  }).catchError((e) {
  });
}
